home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 701-725 / 707 / rayshade / raysh4pl6.zoo / raypaint / xgraphics.c < prev   
C/C++ Source or Header  |  1991-08-08  |  8KB  |  288 lines

  1. /*
  2.  * xgraphics.c
  3.  *
  4.  * Copyright (C) 1989, 1991 Craig E. Kolb, Rod G. Bogart
  5.  *
  6.  * This software may be freely copied, modified, and redistributed
  7.  * provided that this copyright notice is preserved on all copies.
  8.  *
  9.  * You may not distribute this software, in whole or in part, as part of
  10.  * any commercial product without the express consent of the authors.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software
  13.  * for any purpose.  It is provided solely "as is".
  14.  *
  15.  * $Id: xgraphics.c,v 4.0 91/07/17 17:37:32 kolb Exp Locker: kolb $
  16.  *
  17.  * $Log:    xgraphics.c,v $
  18.  * Revision 4.0  91/07/17  17:37:32  kolb
  19.  * Initial version.
  20.  * 
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <math.h>
  25. #include <X11/Xlib.h>
  26. #include <X11/Xutil.h>
  27.  
  28. char *display_name = NULL;
  29. Display *dpy = NULL;
  30. Screen *scrn;
  31. Visual *vis;
  32. Colormap cmap;
  33. GC gc;
  34. Window win;
  35. int screen_height;
  36.  
  37. unsigned long graymap[256];
  38. int max_colors;
  39. double one_over_gamma = 0.4;
  40.  
  41. /*****************************************************************
  42.  * Sets the gray color map for the device.  A 2.5 gamma map is used
  43.  * by default.
  44.  */
  45. setup_gray_gamma_map()
  46. {
  47.     int cc, col;
  48.     int gamma_color;
  49.  
  50.     XColor xcolor;
  51.  
  52.     /* Use the default colormap if possible. */
  53.     if ( vis == DefaultVisualOfScreen( scrn ) )
  54.         cmap = DefaultColormapOfScreen( scrn );
  55.     else
  56.         cmap = XCreateColormap( dpy, RootWindowOfScreen( scrn ),
  57.                                vis, AllocNone );
  58.  
  59.     /* try to share with current colormap */
  60.     for (max_colors = 256; max_colors >= 16; max_colors = max_colors >> 1) {
  61.         xcolor.flags= DoRed | DoGreen | DoBlue;
  62.         for(col=0; col < max_colors; col++) {
  63.             gamma_color = (pow((float) col / (float) max_colors,
  64.                                one_over_gamma) * 65536);
  65.             xcolor.red= gamma_color;
  66.             xcolor.green= gamma_color;
  67.             xcolor.blue= gamma_color;
  68.             if (!XAllocColor(dpy, cmap, &xcolor)) {
  69.                 for (cc=0; cc < col; cc++)
  70.                     XFreeColors(dpy, cmap, &graymap[cc], 1, 0);
  71.                 col = 0;
  72.                 break;
  73.             }
  74.             graymap[col] = xcolor.pixel;
  75.         }
  76.         if (col)
  77.             return;
  78.     }
  79.  
  80.     /* use new map */
  81.     cmap = XCreateColormap( dpy, RootWindowOfScreen( scrn ),
  82.                            vis, AllocNone );
  83.     if (cmap == NULL)  {
  84.         fprintf(stderr, "Could not create color map for visual\n");
  85.         exit(-2);
  86.     }
  87.     for(cc=0; cc < 256; cc++)
  88.         if (!XAllocColorCells(dpy, cmap, False, NULL, 0, &graymap[cc], 1))
  89.             break;
  90.     max_colors = cc;
  91.  
  92.     xcolor.flags= DoRed | DoGreen | DoBlue;
  93.     for(col=0; col < max_colors; col++) {
  94.         xcolor.pixel= graymap[col];
  95.         gamma_color = (pow((float) col / (float) max_colors,
  96.                            one_over_gamma) * 65536);
  97.         xcolor.red= gamma_color;
  98.         xcolor.green= gamma_color;
  99.         xcolor.blue= gamma_color;
  100.         XStoreColor(dpy, cmap, &xcolor);
  101.     }
  102. }
  103.  
  104. GraphicsInit(xsize, ysize, name)
  105. int xsize, ysize;
  106. char *name;
  107. {
  108.     int win_size;
  109.     XSetWindowAttributes attrs;
  110.     XSizeHints sh;
  111.  
  112.     /* Open the display. */
  113.     if ( ! dpy )
  114.     {
  115.         XVisualInfo vis_temp, *vis_list, *max_vis;
  116.         int n_ret, i;
  117.  
  118.         dpy = XOpenDisplay( display_name );
  119.         if ( ! dpy )
  120.         {
  121.             fprintf( stderr, "rayview: Can't open display %s\n",
  122.                      XDisplayName( display_name ) );
  123.             exit(1);
  124.         }
  125.  
  126.         /* Get a PseudoColor visual that has the maximum number of planes. */
  127.         vis_temp.class = PseudoColor;
  128.         vis_list = XGetVisualInfo( dpy, VisualClassMask, &vis_temp, &n_ret );
  129.         if ( n_ret == 0 )
  130.         {
  131.             fprintf(stderr,
  132.                     "Can't find any PseudoColor visual from display %s.\n",
  133.                     XDisplayName( display_name ));
  134.             exit(1);
  135.         }
  136.         max_vis = &vis_list[0];
  137.         for ( i = 1; i < n_ret; i++ )
  138.         {
  139.             if ( max_vis->depth < vis_list[i].depth )
  140.                 max_vis = &vis_list[i];
  141.         }
  142.         vis = max_vis->visual;
  143.         scrn = ScreenOfDisplay( dpy, max_vis->screen );
  144.         gc = DefaultGCOfScreen( scrn );
  145.  
  146.         setup_gray_gamma_map();
  147.  
  148.         XFree( (char *)vis_list );
  149.     }
  150.  
  151.     screen_height = ysize;
  152.  
  153.     attrs.backing_store = Always;
  154.     attrs.colormap = cmap;
  155.     attrs.event_mask = ExposureMask;
  156.     attrs.background_pixel = BlackPixelOfScreen(scrn);
  157.     attrs.border_pixel = WhitePixelOfScreen(scrn);
  158.  
  159.     win = XCreateWindow( dpy, RootWindowOfScreen( scrn ),
  160.                          0, 0, xsize, ysize, 2,
  161.                          0, 0, vis,
  162.                          CWBackingStore | CWColormap | CWEventMask |
  163.                          CWBackPixel | CWBorderPixel,
  164.                          &attrs );
  165.  
  166.     sh.flags = PSize | PMinSize | PMaxSize;
  167.     sh.width = sh.min_width = sh.max_width = xsize;
  168.     sh.height = sh.min_height = sh.max_height = ysize;
  169.     XSetStandardProperties( dpy, win, name, name, None, NULL, 0, &sh );
  170.  
  171.     XMapWindow( dpy, win );
  172.  
  173.     XFlush( dpy );
  174. }
  175.  
  176. /*
  177.  * Draw the pixel at (xp, yp) in the color given by the rgb-triple,
  178.  * 0 indicating 0 intensity, 255 max intensity.
  179.  */
  180. GraphicsDrawPixel(xp, yp, color)
  181. int xp, yp;
  182. unsigned char color[3];
  183. {
  184.     float bwvalue;
  185.     int val;
  186.  
  187.     bwvalue = ( 0.35*color[0] + 0.55*color[1] + 0.10*color[2] ) / 256.0;
  188.     val = (int) ( bwvalue * max_colors );
  189.     XSetForeground( dpy, gc, graymap[val] );
  190.     XFillRectangle( dpy, win, gc, xp, (screen_height - (yp + 1)),
  191.                     1, 1 );
  192. }
  193.  
  194. /*
  195.  * Draw the rect with lower left corner (xp, yp) and upper right
  196.  * corner (xp+ys, yp+ys).  The colors of the l-l, l-r, u-r, and u-l
  197.  * corners are given as arrays of unsigned chars as above.
  198.  */
  199. GraphicsDrawRectangle(xp, yp, xs, ys, ll, lr, ur, ul)
  200. int xp, yp, xs, ys;
  201. unsigned char ll[3], lr[3], ur[3], ul[3];
  202. {
  203.     float bwvalue;
  204.     int val;
  205.  
  206.     bwvalue = ( 0.35*ll[0] + 0.55*ll[1] + 0.10*ll[2] ) / 256.0;
  207.     val = (int) ( bwvalue * max_colors );
  208.     XSetForeground( dpy, gc, graymap[val] );
  209.     XFillRectangle( dpy, win, gc, xp, (screen_height - (yp + ys + 1)),
  210.                     xs+1, ys+1 );
  211.     XFlush( dpy );
  212. }
  213.  
  214. GraphicsLeftMouseEvent()
  215. {
  216.     Window root_ret, child_ret;
  217.     int rx, ry, wx, wy;
  218.     unsigned int mask;
  219.  
  220.     if (XQueryPointer(dpy, win, &root_ret, &child_ret,
  221.                       &rx, &ry, &wx, &wy, &mask)) {
  222.         return mask & Button1Mask;
  223.     }
  224.     else
  225.         return 0;
  226. }
  227.  
  228. GraphicsMiddleMouseEvent()
  229. {
  230.     Window root_ret, child_ret;
  231.     int rx, ry, wx, wy;
  232.     unsigned int mask;
  233.  
  234.     if (XQueryPointer(dpy, win, &root_ret, &child_ret,
  235.                       &rx, &ry, &wx, &wy, &mask)) {
  236.         return mask & Button2Mask;
  237.     }
  238.     else
  239.         return 0;
  240. }
  241.  
  242. GraphicsRightMouseEvent()
  243. {
  244.     Window root_ret, child_ret;
  245.     int rx, ry, wx, wy;
  246.     unsigned int mask;
  247.  
  248.     if (XQueryPointer(dpy, win, &root_ret, &child_ret,
  249.                       &rx, &ry, &wx, &wy, &mask)) {
  250.         return mask & Button3Mask;
  251.     }
  252.     else
  253.         return 0;
  254. }
  255.  
  256. GraphicsGetMousePos(x, y)
  257. int *x, *y;
  258. {
  259.     Window root_ret, child_ret;
  260.     int rx, ry, wx, wy;
  261.     unsigned int mask;
  262.  
  263.     if (XQueryPointer(dpy, win, &root_ret, &child_ret,
  264.                       &rx, &ry, &wx, &wy, &mask)) {
  265.         *x = wx;
  266.         *y = screen_height - wy - 1;
  267.     }
  268.     else {
  269.         *x = 0;
  270.         *y = 0;
  271.     }
  272. }
  273.  
  274. GraphicsRedraw()
  275. {
  276.         XEvent event;
  277.         if (XCheckTypedEvent(dpy, Expose, &event)) {
  278.                 XSetForeground( dpy, gc, graymap[0] );
  279.                 XFillRectangle( dpy, win, gc, event.xexpose.x, event.xexpose.y,
  280.                     event.xexpose.width, event.xexpose.height );
  281.                 XFlush( dpy );
  282.                 return 1;
  283.         }
  284.         else
  285.                 return 0;
  286. }
  287.  
  288.